package educar.models;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import educar.db.JPA;


/**
 *En esta clase se encuentran lo metodos necesario para que un Administrador 
 * pueda administrar un Usuario.
 */
public class User {
    
    private static JPA jpa = new JPA(); //Atributo <code>JPA</code> usado para cear una instancia que contenga un query
    private String username;   //<code>String</code> usada para almacenar el nombre de un usuario.
    private String password;   //<code>String</code> usada para almacenar el password de un usuario.
    private String role;   //<code>String</code> usada para almacenar el rol de un usuario.

    
    /**
     * <hr>
     * User(): Contructor con parametros de la clase User.
     * <hr>
     * @param username
     * @param password
     * @param role
     */
    public User(String username, String password, String role) {
        this.setUsername(username);
	this.setPassword(password);
	this.setRole(role);
    }//Fin del metodo User(String, String, String).
    
    
    /**
     * @author Flubber
     * <hr>
     * User(): Constructor que recibe como parametro un arreglo.
     * <hr>
     * @param user Un <code>String[]</code> que contiene los datos necesarios para de un user.
     */
    public User(String[] user) {
        this.setUsername(user[0]);
	this.setPassword(user[1]);
	this.setRole(user[2]);
    }//Fin del metodo Resolucion(String[])

    
    /**
     * <hr>
     * authenticate(): Verifca que no haya otro elemento con los mismos atributos en la base de datos.
     * <hr>
     * @param username
     * @param password
     * @return <code>true</code> si no exite otro elemento con los mismos atributos en la base de datos
     * o <code>false</code> en caso contrario.
     */ 
    public static boolean authenticate(String username, String password) {
        try {
            User u = getUserByUsername(username);
            if (password.equals(u.getPassword())) {
                Session.setCurrentUser(u);
		return true;
            }
	} catch (userNotFound ex) {
            return false;
	}
	return false;
    }//Fin del metodo authenticate(String, String)

    
    /**
     * <hr>
     * save():Guarda un usuario en la base de datos.
     * Intenta obtener un usuario de la base de datos si lo logra o
     * por cualquier problema que ocurra al intentar obtenerlo o guardarlo retorna false, 
     * pero si logra guardar el usuario retorna true.
     * <hr>
     * @return <code>true</code> si logra guardar el usuario,
     * <code>false</code> si ya existe el elemento o que ocurra algun problema.
     */ 
    public boolean save() {
        try {   //Se intenta obtener un usuario
            User.getUserByUsername(username);
            return false;
	} catch (userNotFound e1) {
            String[] columns = { "username", "password", "role" };
            PreparedStatement stm = jpa.newRecord("educar_dev.users", columns);
            try {   //Intenta setear los datos
                stm.setString(1, username);
		stm.setString(2, password);
		stm.setString(3, role);
            } catch (SQLException e) {  //Ocurrio un error al intentar ingresar el usuario
                e.printStackTrace();
		return false;
            }
            jpa.create(stm);    //Guarda el usuario en la base de datos
            return true;
	}
    }//Fin del metodo save()

    
    /**
     * <hr> 
     * destroy(): Elimina un usuario de la base de datos.
     * <hr>
     */
    public void destroy() {
        jpa.destroy("users", "username", this.getUsername());
    }//Fin del metodo destroy()

    
    /**
     * <hr>
     * destroyUserByUsername(): Metodo estatico usado para eliminar un elemento de la base de datos.
     * <hr>
     * @param username 
     */
    public static void destroyUserByUsername(String username) {
        jpa.destroy("users", "username", username);
    }//Fin del metodo destroy(String)

    
    /**
     * <hr>
     * getUserByUsername(): Dado el username de un usuario, consulto la base de datos
     * usando este username para obtener todos los datos del mismo, en el caso que este 
     * no se encuentre lanza una excepcion userNotFound.
     * <hr>
     * @param username
     * @return User
     * @throws userNotFound 
     */
    public static User getUserByUsername(String username) throws userNotFound {
        //Consulto en la base de datos la tabla users, usando username como clave
        ResultSet rs = null;
	User u = null;
	rs = jpa.getByField("users", "username", username);
	try {
            if (rs.next()) {
                u = new User(rs.getString(2), rs.getString(3), rs.getString(4));
            } else {
                throw new userNotFound();
            }
	} catch (SQLException e) {
            e.printStackTrace();
	}
	return u;
    }//Fin del metodo getUserByUsername(String).
 
    
    /**
     * @author Flubber
     * <hr>
     * setUserByUsername(): Este metodo modifica a un usuario usando su username.
     * <hr>
     * @param oldusername username del usuario que quiero modificar
     */
    public boolean setUserByUsername(String oldusername) {
        ResultSet rs = null;
        String id;
	rs = jpa.getByField("users", "username", oldusername);
	try {
            if (rs.next()) {
                id = rs.getString(1);
            } else {
                return false;
            }
	} catch (SQLException e) {
            e.printStackTrace();
            return false;
	}
        jpa.update("users", "username", username,"id", id);
        jpa.update("users", "password", password,"id", id);
        jpa.update("users", "role", role,"id", id);           
	return true;
    }//Fin de la clase setUserByUsername(String)
        
    public String getUsername() {
	return username;
    }

    public void setUsername(String username) {
	this.username = username;
    }

    public String getPassword() {
    	return password;
    }

    public void setPassword(String password) {
    	this.password = password;
    }

    public String getRole() {
	return role;
    }

    public void setRole(String role) {
	this.role = role;
    }
}//Fin de la clase Resolucion.
